package com.everbest.flowable;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;

import com.everbest.flowable.mybatisbean.FinishTaskEntity;
import com.everbest.flowable.mybatisbean.WorkFlowRecordEntity;

public interface WorkFlowUtil {

    /**
     * 部署流程 文件需要存放在resources/processes目录下
     * 
     * @param bpmnFileName
     *            文件名
     * @param processId
     *            文件里定义的id
     * @param processName
     *            文件里定义的name
     * @return 返回部署结果对象
     */
    ResultBean deploy(String bpmnFileName, String processId, String processName);

    /**
     * 启动流程实例
     * 
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @return 结果对象
     */
    ResultBean start(String processDefinitionKey);

    /**
     * 启动流程实例
     * 
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @param businessKey
     *            需要绑定到流程里的业务id
     * @return 包含流程实例对象的结果
     */
    ResultBean<ProcessInstance> start(String processDefinitionKey, String businessKey);

    /**
     * 启动流程实例
     * 
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @param businessKey
     *            需要绑定到流程里的业务id
     * @param variables
     *            需要设置的流程变量
     * @return 包含流程实例对象的结果
     */
    ResultBean<ProcessInstance> start(String processDefinitionKey, String businessKey, Map<String, Object> variables);

    /**
     * 时间倒序查询用户所有的任务
     * 
     * @param assignee
     *            用户的id
     * @return 任务对象集合
     */
    ResultBean<List<Task>> selectAllTasks(String assignee);

    /**
     * 时间倒序查询用户的以及用户组织机构下的所有任务
     * 
     * @param assignee
     *            用户的id
     * @param orgId
     *            组织机构的id
     * @return 返回包含任务集合的结果对象
     */
    ResultBean<List<Task>> selectGroupTasks(String assignee, String orgId);

    /**
     * 时间倒序查询用户的以及用户组织机构下指定流程的所有任务
     * 
     * @param assignee
     *            用户的id
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @param orgId
     *            组织机构的id
     * @return 返回包含任务集合的结果对象
     */
    ResultBean<List<Task>> selectGroupTasks(String assignee, String processDefinitionKey, String orgId);

    /**
     * 时间倒序查询用户部分的任务
     * 
     * @param assignee
     *            用户的id
     * @param limit
     *            限制条数
     * @return 任务对象集合
     */
    ResultBean<List<Task>> selectAllTasks(String assignee, int limit);

    /**
     * 时间倒序分页查询用户的任务
     * 
     * @param assignee
     *            用户的id
     * @param firstNum
     *            开始序号
     * @param length
     *            查询条数
     * @return 任务对象集合
     */
    ResultBean<List<Task>> selectAllTasks(String assignee, int firstNum, int length);

    /**
     * 时间倒序查询用户某个流程所有的任务
     * 
     * @param assignee
     *            用户的id
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @return 包含人任务对象集合的结果对象
     */
    ResultBean<List<Task>> selectAllTasks(String assignee, String processDefinitionKey);

    /**
     * 查询指定用户指定工作流的代办任务数量
     * 
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @return 包含指定工作流的代办任务数据的结果对象
     */
    ResultBean<Integer> selectAllTasksCount(String processDefinitionKey, String taskDefinitionKey);

    /**
     * 查询指定用户指定工作流的代办任务数量
     * 
     * @param assignee
     *            用户的id
     * @param processDefinitionKey
     *            流程文件里定义的id
     * @param taskDefinitionKey
     *            流程图里定义的节点id
     * @return 包含指定工作流的代办任务数据的结果对象
     */
    ResultBean<Integer> selectAllTasksCount(String assignee, String processDefinitionKey, String taskDefinitionKey);

    /**
     * 时间倒序查询用户某个流程所有的任务
     * 
     * @param assignee
     *            用户的id
     * @param instanceId
     *            流程流程实例id
     * @return 包含人任务对象集合的结果对象
     */
    ResultBean<List<Task>> selectTasks(String assignee, String instanceId);

    /**
     * 查询用户某个流程所有的任务
     * 
     * @param assignee
     *            用户的id
     * @param taskId
     *            任务id
     * @return 包含任务对象的结果对象
     */
    ResultBean<Task> selectTask(String assignee, String taskId);

    /**
     * 查询当前任务的审批人id
     * 
     * @param instanceId
     *            流程实例id
     * @return 包含用户id的结果对象
     */
    ResultBean<String> selectNextApprovalId(String instanceId);

    /**
     * 查询用户某个流程所有的任务
     * 
     * @param assignee
     *            用户的id
     * @param instanceId
     *            流程流程实例id
     * @param taskDefinitionKey
     *            流程图里定义的节点id
     * @return 包含任务对象的结果对象
     */
    ResultBean<Task> selectTask(String assignee, String instanceId, String taskDefinitionKey);

    /**
     * 查询一个正在执行的任务
     * 
     * @param taskId
     *            任务id
     * @return 任务对象集合
     */
    ResultBean<Task> selectTask(String taskId);

    /**
     * 查询流程实例的当前的一个任务
     * 
     * @param instanceId
     *            流程流程实例id
     * @return 任务对象集合
     */
    ResultBean<Task> selectCurrentTask(String instanceId);

    /**
     * 查询当前登录用户是否有指定实例和节点下的任务
     * 
     * @param userId
     *            用户序号
     * @param instanceId
     *            流程实例id
     * @param taskDefinitionKey
     *            流程图里定义的节点id
     * @return 包含任务id的结果对象
     */
    ResultBean<String> selectTaskId(Long userId, String instanceId, String taskDefinitionKey);

    /**
     * 查询一个历史任务
     * 
     * @param taskId
     *            任务id
     * @return 包含历史任务对象的结果对象
     */
    ResultBean<HistoricTaskInstance> selectHistoryTask(String taskId);

    /**
     * 拾取任务，用于分配给组的任务,拾取就是分配任务到具体的某个人
     * 
     * @param taskId
     *            任务id
     * @param assignee
     *            任务责任人id
     * @return 结果对象
     */
    ResultBean pickingTask(String taskId, String assignee);

    /**
     * 获取启动流程实例时设置的业务id
     * 
     * @param taskId
     *            任务id
     * @return 包含业务id的结果对象
     */
    ResultBean<String> selectBusinessKey(String taskId);

    /**
     * 获取启动流程实例时设置的业务id
     * 
     * @param task
     *            任务d对象
     * @return 包含业务id的结果对象
     */
    ResultBean<String> selectBusinessKey(Task task);

    /**
     * 获取流程实例时设置的业务id
     * 
     * @param instanceId
     *            流程实例id
     * @return 包含业务id的结果对象
     */
    ResultBean<String> selectBusinessKeyByInstanceId(String instanceId);

    /**
     * 获取多个任务对应的业务id
     * 
     * @param task
     *            任务对象
     * @return 包含业务id的结果对象
     */
    ResultBean<Set<String>> selectBusinessKeys(List<Task> task);

    /**
     * 获取指定实例人参与的工作流历史记录
     * 
     * @param instanceId
     *            流程实例id
     * @return 包含历史审批记录的结果对象
     */
    ResultBean<List<HistoricActivityInstance>> selectHistory(String instanceId);

    /**
     * 获取指定实例人参与的工作流历史记录
     * 
     * @param instanceId
     *            流程实例id
     * @return 包含历史审批记录的结果记录对象
     */
    ResultBean<List<WorkFlowRecordEntity>> selectHistoryRecord(String instanceId);

    /**
     * 获取指定流程实例的所有工作流历史记录
     * 
     * @param instanceId
     *            流程实例id
     * @return 包含历史审批记录的结果对象
     */
    ResultBean<List<HistoricActivityInstance>> selectFlowHistory(String instanceId);

    /**
     * 返回指定流程实例并且指定流程节点的历史审批人
     * 
     * @param instanceId
     *            流程实例id
     * @param taskDefinitionKey
     *            流程图里定义的节点id
     * @return 包含历史审批人信息的结果对象
     */
    ResultBean<String> selectAssigneeFromHistory(String instanceId, String taskDefinitionKey);

    /**
     * 判断指定流程实例是否已经完成
     * 
     * @param instanceId
     *            流程实例id
     * @return 包含实例是否完成的结果对象
     */
    ResultBean<Boolean> isFinish(String instanceId);

    /**
     * 完成任务
     * 
     * @param assignee
     *            任务的所有人
     * @param taskId
     *            任务id
     * @return 完成结果
     */
    ResultBean finishTask(String assignee, String taskId);

    /**
     * 完成任务
     * 
     * @param assignee
     *            任务的所有人
     * @param taskId
     *            任务id
     * @param variables
     *            需要设置的流程参数
     * @return 完成结果
     */
    ResultBean finishTask(String assignee, String taskId, Map<String, Object> variables);

    /**
     * 完成任务并且填写备注
     * 
     * @param finishTaskEntity
     *            完成任务所需的信息对象
     * @return 完成结果
     */
    ResultBean finishTaskWithComment(FinishTaskEntity finishTaskEntity);

    /**
     * 添加备注
     * 
     * @param taskId
     *            任务id
     * @param instanceId
     *            流程实例id
     * @param message
     *            备注的消息数组
     * @return 返回是否成功的结果对象
     */
    ResultBean addComment(String taskId, String instanceId, String... message);

    /**
     * 完成任务，并且把流程下一个节点的任务根据历史记录自动拾取
     * 
     * @param assignee
     *            任务所有人
     * @param taskId
     *            任务id
     * @param variables
     *            需要设置的流程参数
     * @return 完成结果
     */
    ResultBean finishTaskTidyGroup(String assignee, String taskId, Map<String, Object> variables);

    /**
     * 获取流程变量的值
     * 
     * @param instanceId
     *            流程实例id
     * @param key
     *            变量的key
     * @return
     */
    ResultBean<Object> getVariable(String instanceId, String key);

    /**
     * 删除一个流程实例
     * 
     * @param instanceId
     *            流程实例的id
     * @param deleteReason
     *            删除的原因
     * @return 删除结果
     */
    ResultBean deleteInstance(String instanceId, String deleteReason);

    /**
     * 删除流程的定义
     * 
     * @param definitionKey
     *            流程定义的id
     * @return
     */
    ResultBean deleteDefinition(String definitionKey);

    /**
     * 删除流程的定义，如果级联删除则会把定义等信息删除掉
     * 
     * @param definitionKey
     *            流程定义的id
     * @param cascade
     *            是否需要级联删除
     * @return
     */
    ResultBean deleteDefinition(String definitionKey, boolean cascade);

}
